package algorithm.dp;

public class 扰乱字符串N {
/*
 * 给定一个字符串 s1，我们可以把它递归地分割成两个非空子字符串，从而将其表示为二叉树。

下图是字符串 s1 = "great" 的一种可能的表示形式。

    great
   /    \
  gr    eat
 / \    /  \
g   r  e   at
           / \
          a   t
在扰乱这个字符串的过程中，我们可以挑选任何一个非叶节点，然后交换它的两个子节点。

例如，如果我们挑选非叶节点 "gr" ，交换它的两个子节点，将会产生扰乱字符串 "rgeat" 。

    rgeat
   /    \
  rg    eat
 / \    /  \
r   g  e   at
           / \
          a   t
我们将 "rgeat” 称作 "great" 的一个扰乱字符串。

同样地，如果我们继续将其节点 "eat" 和 "at" 进行交换，将会产生另一个新的扰乱字符串 "rgtae" 。

    rgtae
   /    \
  rg    tae
 / \    /  \
r   g  ta  e
       / \
      t   a
我们将 "rgtae” 称作 "great" 的一个扰乱字符串。

给出两个长度相等的字符串 s1 和 s2，判断 s2 是否是 s1 的扰乱字符串。

示例 1:

输入: s1 = "great", s2 = "rgeat"
输出: true
示例 2:

输入: s1 = "abcde", s2 = "caebd"
输出: false
 */
    public boolean isScramble(String s1, String s2) {
        /*
         * 1、只能挑选非叶节点进行扰乱 2、递归分割时必须是非空字符串
         * 那么：1、对于字符串s1[m:i],s2[m:i]是对应的扰乱字符串，s1[i+1:j],与s2[i+1:j]是对应的扰乱字符串
         * 2、如果dp[i][j]是扰乱字符串，dp[j][k]是扰乱字符串，那么dp[i][k]也是扰乱字符串，其中i<=j<=k
         * 3、初始的扰乱字符串一定邻近的2个
         */
        int len = s1.length();
        if (s2.length() != len) {
            return false;
        }

        boolean[][] dp = new boolean[len + 5][len + 5];
        for (int i = 0; i < len - 1; i++) {
            if (s1.charAt(i) == s2.charAt(i + 1) && s1.charAt(i + 1) == s2.charAt(i)) {
                dp[i][i + 1] = true;
            }
        }
        for (int i = 0; i < len; i++) {
            if (s1.charAt(i) == s2.charAt(i)) {
                dp[i][i] = true;
            }
        }
        for (int k = 1; k < len; k++) {
            for (int i = 0; i + k < len; i++) {
                for (int m = 0; m < k && i + m < len; m++) {
                    if (dp[i][i + m] && dp[i + m + 1][i + k]) {
                        dp[i][i + k] = true;
                        break;
                    }
                }
            }
        }
        return dp[0][len - 1];
    }

    public static void main(String[] args) {
        扰乱字符串N run = new 扰乱字符串N();
        System.out.println(run.isScramble("abb", "bba"));
    }
}
